package com.fuyao.cloud.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.admin.api.dto.UserInfoParamsDTO;
import com.fuyao.cloud.admin.api.entity.*;
import com.fuyao.cloud.admin.api.vo.UserInfoDeptVO;
import com.fuyao.cloud.admin.api.vo.UserVO;
import com.fuyao.cloud.admin.constant.UserConstants;
import com.fuyao.cloud.admin.mapper.EgdOrgJobtitleMapper;
import com.fuyao.cloud.admin.mapper.EgdOrgUserMapper;
import com.fuyao.cloud.admin.mapper.SysUserMapper;
import com.fuyao.cloud.admin.mapper.SysUserinfoMapper;
import com.fuyao.cloud.admin.service.EgdOuInfoService;
import com.fuyao.cloud.admin.service.EgdUserInfoService;
import com.fuyao.cloud.admin.service.SysPublicParamService;
import com.fuyao.cloud.admin.service.SysUserinfoService;
import com.fuyao.cloud.common.core.util.R;
import com.fuyao.cloud.common.data.datascope.DataScope;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 人员信息
 *
 * @author 碎月
 * @date 2021-12-16 10:32:13
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysUserinfoServiceImpl extends ServiceImpl<SysUserinfoMapper, SysUserinfo> implements SysUserinfoService {

    private final SysUserMapper userMapper;

    private final SysPublicParamService publicParamService;

    private final SysUserinfoMapper userinfoMapper;

    private final EgdUserInfoService egdUserInfoService;

    private final EgdOrgUserMapper orgUserMapper;

    private final EgdOuInfoService ouInfoService;

    private final EgdOrgJobtitleMapper orgJobtitleMapper;

    @Override
    public boolean save(SysUserinfo entity) {
        entity.setId(null);
        return super.save(entity);
    }

    @Override
    public boolean updateById(SysUserinfo entity) {
        return super.updateById(entity);
    }

    @Override
    public SysUserinfo getUserInfoByUserName(String userName) {
        SysUserinfo sysUserinfo = this.baseMapper.selectOne(Wrappers.<SysUserinfo>lambdaQuery().eq(SysUserinfo::getLoginname, userName));
        return sysUserinfo;
    }

    /**
     *
     * @param userNumbers
     * @return
     */
    @Override
    public R<Map<String,String>> getMobiles(List<String> userNumbers) {
        List<SysUserinfo> userinfos= this.baseMapper.selectList(Wrappers.<SysUserinfo>lambdaQuery().in(SysUserinfo::getPersonNumber,userNumbers));
        Map<String,String> mobiles= userinfos.stream().collect(Collectors.toMap(SysUserinfo::getPersonNumber,SysUserinfo::getMobile,(oldKey, newKey)->newKey));
        return R.ok(mobiles);

    }

    @Override
    public List<Tree<Long>> selectTree() {
        // 查询全部部门
        List<SysUserinfo> userinfoList = baseMapper.selectList(Wrappers.emptyWrapper());
        // 查询数据权限内部门
        List<Long> userOwnIdList = baseMapper.selectListByScope(Wrappers.emptyWrapper(), new DataScope()).stream()
                .map(SysUserinfo::getId).collect(Collectors.toList());

        // 权限内部门
        List<TreeNode<Long>> collect = userinfoList.stream()
                .sorted(Comparator.comparing(SysUserinfo::getCreateTime)).map(user -> {
                    TreeNode<Long> treeNode = new TreeNode();
                    treeNode.setId(user.getId());
                    treeNode.setParentId(0L);
                    treeNode.setName(user.getName());
                    treeNode.setWeight(user.getCreateTime());
                    // 有权限不返回标识
                    Map<String, Object> extra = new HashMap<>(8);
                    extra.put("isLock", !userOwnIdList.contains(user.getUserId()));
                    extra.put("createTime", user.getCreateTime());
                    extra.put("deptName", (CollUtil.getLast(StrUtil.split(user.getDeptFullname(),"."))));
                    extra.put("deptFullname", user.getCreateTime());
                    treeNode.setExtra(extra);
                    return treeNode;
                }).collect(Collectors.toList());

        return TreeUtil.build(collect, 0L);
    }

    /**
     * 保证人事系统与OA系统用户数据一致
     * 更新远程数据库
     * @return
     */
    @Override
    public R updateRemoteDatabase() {
        // 获取上次更新的时间戳
        String updateTime= this.publicParamService.getSysPublicParamKeyToValue("USER_UPDATE_TIME");
        // 查询新增或者修改过的用户数据
        List<SysUserinfo> userinfos= this.userinfoMapper.selectList(Wrappers.<SysUserinfo>lambdaQuery().gt(SysUserinfo::
                getCreateTime,updateTime).or().gt(SysUserinfo::getUpdateTime,updateTime));
        EgdOrgUserinfo orgUser;
        for (int i = 0; i < userinfos.size(); i++) {
            SysUserinfo userinfo =userinfos.get(i);
            orgUser = this.egdUserInfoService.getOne(Wrappers.<EgdOrgUserinfo>lambdaQuery()
                    .eq(EgdOrgUserinfo::getPersonNumber, userinfo.getPersonNumber()));
            if (orgUser == null){
                orgUser = this.egdUserInfoService.getOne(Wrappers.<EgdOrgUserinfo>lambdaQuery().eq(EgdOrgUserinfo::getName
                        , userinfo.getName()).and( p -> p.eq(EgdOrgUserinfo::getUserLigion,userinfo.getLoginname())));
                if (orgUser == null) {
                    insertEgdOrgUserinfo(userinfo);
                } else {
                    updateEgdOrgUserinfo(orgUser,userinfo);
                }
            } else {
                updateEgdOrgUserinfo(orgUser,userinfo);
            }
        }
        // 更新时间戳
        SysPublicParam publicParam= this.publicParamService.getOne(Wrappers.<SysPublicParam>lambdaQuery().eq(SysPublicParam::getPublicKey,"USER_UPDATE_TIME"));
        publicParam.setPublicValue(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
        this.publicParamService.updateParam(publicParam);
        return R.ok("更新成功");
    }

    @SneakyThrows
    @Override
    public R syncOaData() {
        log.info("同步数据开始：{}",LocalDateTime.now());
        boolean dept = ouInfoService.syncOaOuInfoToDept();
        Thread.sleep(3000L);
        boolean user = egdUserInfoService.syncOaUserInfoToUser();
        log.info("同步数据结束：{}",LocalDateTime.now());

        if(dept && user){
            return R.ok("同步oa数据成功");
        }
        return R.failed("同步oa数据失败");
    }

    @Override
    public boolean saveOrUpdateUserinfo(SysUser sysUser) {
        SysUserinfo userinfo = this.userinfoMapper.selectOne(Wrappers.<SysUserinfo>query().lambda().eq(SysUserinfo::getUserId, sysUser.getUserId()));
        if(null == userinfo){
            userinfo = new SysUserinfo();
        }
        userinfo.setUserId(sysUser.getUserId());
        userinfo.setLoginname(sysUser.getUsername());
        userinfo.setName(sysUser.getName());
        userinfo.setPersonNumber(getPersonNumber());
        userinfo.setCardId(userinfo.getPersonNumber());
        userinfo.setMobile(sysUser.getPhone());
        return this.saveOrUpdate(userinfo);
    }

    @Override
    public List<UserInfoDeptVO> getUserDetailInfoList(UserInfoParamsDTO userInfoParamsDTO) {
        return this.userinfoMapper.getUserDetailInfoList(userInfoParamsDTO);
    }

    private void updateEgdOrgUserinfo(EgdOrgUserinfo orgUserinfo,SysUserinfo userinfo) {
        orgUserinfo.setName(userinfo.getName());
        orgUserinfo.setGender(Integer.valueOf(userinfo.getGender()));
        orgUserinfo.setBirthday(LocalDateTime.of(userinfo.getBirthday(), LocalTime.of(0,0,0)));
        orgUserinfo.setEmail(userinfo.getEmail());
        orgUserinfo.setMobile(userinfo.getMobile());
        orgUserinfo.setTelephoneno(userinfo.getTelephone());
        orgUserinfo.setFaxno(userinfo.getFaxno());
        orgUserinfo.setCardId(userinfo.getCardId());
//		orgUserinfo.setOuInfoId();
//		orgUserinfo.setJobTitleId();
        this.egdUserInfoService.updateByIdAndUnid(orgUserinfo);
    }

    private void insertEgdOrgUserinfo(SysUserinfo userinfo) {
        EgdOrgUserinfo orgUserinfo=new EgdOrgUserinfo();
        orgUserinfo.setName(userinfo.getName());
        if (userinfo.getGender() != null){
            orgUserinfo.setGender(Integer.valueOf(userinfo.getGender()));
        }else {
            orgUserinfo.setGender(2);
        }
        if(userinfo.getBirthday() !=null){
            orgUserinfo.setBirthday(LocalDateTime.of(userinfo.getBirthday() , LocalTime.of(0,0,0)));
        }else {
            orgUserinfo.setBirthday(LocalDateTime.now());
        }
        orgUserinfo.setEmail(userinfo.getEmail() == null ? "" :userinfo.getEmail());
        orgUserinfo.setMobile(userinfo.getMobile() == null ? "" : userinfo.getMobile());
        orgUserinfo.setTelephoneno(userinfo.getTelephone() == null ? "" : userinfo.getTelephone());
        orgUserinfo.setFaxno(userinfo.getFaxno() == null ? "" : userinfo.getFaxno());
        orgUserinfo.setCardId(userinfo.getCardId() == null ? "" : userinfo.getCardId());
        orgUserinfo.setPersonNumber(userinfo.getPersonNumber());
        UserVO userVO= this.userMapper.getUserVoById(userinfo.getUserId());
        EgdOrgOuinfo orgOuinfo= this.ouInfoService.getOne(Wrappers.<EgdOrgOuinfo>lambdaQuery().eq(EgdOrgOuinfo::getFullcode,userVO.getDeptFullCode()));
        if (orgOuinfo != null && orgOuinfo.getId() != null){
            orgUserinfo.setOuInfoId(orgOuinfo.getId());
        }
        EgdOrgJobtitle orgJobtitle= this.orgJobtitleMapper.selectOne(Wrappers.<EgdOrgJobtitle>lambdaQuery().eq(EgdOrgJobtitle::getName,userinfo.getPost()));
        if (orgJobtitle != null && orgJobtitle.getId() != null){
            orgUserinfo.setJobTitleId(orgJobtitle.getId());
        }
        this.egdUserInfoService.insertEgdOrgUserinfo(orgUserinfo);
        Long orgUserInfoId = this.egdUserInfoService.getOne(Wrappers.<EgdOrgUserinfo>lambdaQuery().eq(EgdOrgUserinfo::getPersonNumber,userinfo.getPersonNumber())).getId();
        EgdOrgUser orgUser=new EgdOrgUser();
        orgUser.setName(userinfo.getName());
        orgUser.setLoginName(userinfo.getLoginname());
        orgUser.setLoginPassword("(f379eaf3c831b04de153469d1bec345e)");
        orgUser.setUserinfoId(orgUserInfoId);
        orgUser.setStatus(0);
        orgUser.setType("-1");
        orgUser.setIsUseikey("N");
        orgUser.setIsTmpuser("N");
        this.orgUserMapper.insert(orgUser);
    }

    /**
     * 获取人员编号
     * @return 人号编码
     */
    private String getPersonNumber(){
        return UserConstants.PERSON_NUMBER_PREFIX+ this.userinfoMapper.selectCount(Wrappers.emptyWrapper());
    }
}
